#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/wait.h>
#include<string.h>
#include<sys/types.h>
#define NUM 1024
#define SIZE 32
#define SEP " "
//保存打散的命令行字符串
char *g_argv[SIZE];
//保存完整的命令行字符串
char cmd_line[NUM];
int main()
{
  //.命令行解释器，一定是一个常驻内存的进程，不退出
  while(1)
  {
    //1.打印出提示信息 [lujiaming@hspEdu01 shell]$
    printf("[lujiaming@hspEdu01 shell]$ ");
    fflush(stdout);
    //获取用户的键盘输入信息
    memset(cmd_line,'\0',sizeof cmd_line);
    if(fgets(cmd_line,sizeof cmd_line,stdin)==NULL){
      continue;
    }
    cmd_line[strlen(cmd_line)-1]='\0' ;//下标strlen(cmd_line-1)的位置相当于是字符\n，因为按下回车就是一个\n,strlen函数计算的字符串不包括\0，因此cmd_line[strlen(cmd_line)-1]指向的就是用户输入命令字符串的最后一个字符\n
    
    //printf("echod : %s\n",cmd_line);
    //3."ls -a -l -i" -> "ls" "-a" "-i"
    g_argv[0]=strtok(cmd_line,SEP);//第一次调用，要传入原始字符串
    int index=1;
    if(strcmp(g_argv[0],"ls")==0){
      g_argv[index++]="--color=auto";
    }

    while(g_argv[index++]=strtok(NULL,SEP));//第二次，如果还要解析原始字符串，第一个参数设为NULL
   // for(index =0;g_argv[index];index++)//g_argv[index]相当于遍历数组里面的元素
    //  printf("g_argv[%d]:%s\n",index,g_argv[index]);
    if(strcmp(g_argv[0],"cd")==0){//不想让子进程执行，而是让父进程去执行cd命令
      //让父进程执行的命令叫内置命令（内建命令）,内健命令
      //内建命令本质起始就是shell中的一个函数调用
      if(g_argv[1]!=NULL){
        chdir(g_argv[1]);//更改为g_argv[1]元素对应的目录
        continue;//后面的不用跑了
      }
    }
    pid_t id=fork();
    if(id==0){
      //child
      printf("下面的功能让子进程执行\n");
      execvp(g_argv[0],g_argv);
      exit(1);
    }
    //father
   int status=0;
   pid_t ret=waitpid(id,&status,0);
   if(ret > 0)printf("exit code: %\n",WEXITSTATUS(status));
  }
}
